import 'package:flutter/material.dart';

class Paper extends StatelessWidget {
  const Paper({super.key});

  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.white,
      child: CustomPaint(
        painter: PaperPainter(),
      ),
    );
  }
}

class PaperPainter extends CustomPainter {
  final Paint mPaint = Paint()
    ..style = PaintingStyle.stroke
    ..color = Colors.blue
    ..strokeWidth = 20;
  final Path mPath = Path();

  @override
  void paint(Canvas canvas, Size size) {
    // 绘制圆
    //drawIsAntiAliasColor(canvas);
    //drawStyleStrokeWidth(canvas);
    //drawStrokeCap(canvas);
    //drawStrokeJoin(canvas);
    drawStrokeMiterLimit(canvas);
  }

  /// 测试 isAntiAlias 和 color属性
  void drawIsAntiAliasColor(Canvas canvas) {
    canvas.drawCircle(
        const Offset(120, 150),
        100,
        mPaint
          ..color = Colors.blue
          ..strokeWidth = 5);
    canvas.drawCircle(
        const Offset(360, 150),
        100,
        mPaint
          ..color = Colors.red
          ..isAntiAlias = false);
  }

  /// 测试 style 和 strokeWidth 属性
  void drawStyleStrokeWidth(Canvas canvas) {
    mPaint.color = Colors.red;
    canvas.drawCircle(
        const Offset(180, 180),
        100,
        mPaint
          ..style = PaintingStyle.stroke
          ..strokeWidth = 50);
    canvas.drawCircle(
        const Offset(180 + 360, 180), 100, mPaint..style = PaintingStyle.fill);
  }

  /// 线帽类型
  // StrokeCap.butt - 不出头
  // StrokeCap.round - 圆头
  // StrokeCap.square - 方头
  void drawStrokeCap(Canvas canvas) {
    canvas.drawLine(const Offset(50, 50), const Offset(50, 150),
        mPaint..strokeCap = StrokeCap.butt);
    canvas.drawLine(const Offset(100, 50), const Offset(100, 150),
        mPaint..strokeCap = StrokeCap.round);
    canvas.drawLine(const Offset(150, 50), const Offset(150, 150),
        mPaint..strokeCap = StrokeCap.square);
  }

  /// 线接类型
  // StrokeJoin.bevel - 斜角
  // StrokeJoin.miter - 锐角
  // StrokeJoin.round - 圆角
  void drawStrokeJoin(Canvas canvas) {
    mPath.moveTo(50, 50);
    mPath.lineTo(50, 150);
    mPath.relativeLineTo(100, -50);
    mPath.relativeLineTo(0, 100);
    canvas.drawPath(mPath, mPaint..strokeJoin = StrokeJoin.bevel);

    mPath.reset();
    mPath.moveTo(50 + 150.0, 50);
    mPath.lineTo(50 + 150.0, 150);
    mPath.relativeLineTo(100, -50);
    mPath.relativeLineTo(0, 100);
    canvas.drawPath(mPath, mPaint..strokeJoin = StrokeJoin.miter);

    mPath.reset();
    mPath.moveTo(50 + 150.0 * 2, 50);
    mPath.lineTo(50 + 150.0 * 2, 150);
    mPath.relativeLineTo(100, -50);
    mPath.relativeLineTo(0, 100);
    canvas.drawPath(mPath, mPaint..strokeJoin = StrokeJoin.round);
  }

  /// 斜接限制 strokeMiterLimit只适用于【StrokeJoin.miter】。
  // 它是一个对斜接的限定，如果超过阈值，会变成【StrokeJoin.bevel】。
  // 数字越大，允许出现的尖角就可以越尖
  void drawStrokeMiterLimit(Canvas canvas) {
    for (int i = 0; i < 4; i++) {
      mPath.reset();
      mPath.moveTo(50 + 150.0 * i, 50);
      mPath.lineTo(50 + 150.0 * i, 150);
      mPath.relativeLineTo(100, -(40.0 * i + 20));
      canvas.drawPath(mPath, mPaint..strokeMiterLimit = 2);
    }
    for (int i = 0; i < 4; i++) {
      mPath.reset();
      mPath.moveTo(50 + 150.0 * i, 50 + 150.0);
      mPath.lineTo(50 + 150.0 * i, 150 + 150.0);
      mPath.relativeLineTo(100, -(40.0 * i + 20));
      canvas.drawPath(mPath, mPaint..strokeMiterLimit = 3);
    }
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}
